Introduction:
Insert GODSMACK CD, play 'Release the demons'!
Resources about this subject can be found all over the web, unfortunately only some of them gives you detailed information about the IT and the PE format.. one of the most interesting tutorials out there is by Eduardo Labir aka hav0k.. his tutorial is the one which made me understand how to rewrite the IT of any file.. tnx man.
In this tutuorial I'll try to show you how to reconstructe the IT of a reverseme written by CuTedEviL for my old (dead :[) crew C.O.D.E.
The reverseme is included within this package, but before you run it please make sure the MD5 signature of it is "1B084265DC03B55ACA944A7B3C2F290E" to avoid being tampered with.. you may read the rules within the .doc file included by CuTedEviL to fully understand what we are going to do.
I, at this point, assume that you have read and understood all the above and wanna continue.. so get the tools listed below and get ready for some nice approach.
Tools we'll use:
- LordPE, or any other HEXeditor
- OllyDbg, or any other debugger (GUIed one is prefferd)
- only! ;)
So, let's make IT work:
While yer cracking you must have came accross some functions calls, i.e Call ExitProcessA.. but under any debugger you'll rarely see this kind of call.. if you read hav0k tutorial you see that there are several ways of which we can call a function.. those ways are:
Exit dd "xxxxxxxxh" ; ExitProcessA addr
1- under debugger
push 0
push offset Exit ; where we have the offset of the func.
call ExitProcessA
2- direct jump to the API
jump Kernel32.ExitProcessA ; direct jump to the func. address
What is the Import Table anyhow?
The import table IMHO is where the compiler stores information of each function imported by the program in order for the program to use it. The IT consists of table of RVAs to the IMAGE_IMPORT_DISCRIPTOR each DLL used and a table filled with zeros points to the end of the IT.. we'll be dealing with the RVAs of each DLL, those RVAs are included in what's so called the (IMAGE_IMPORT_DISCRIPTORs) which we will call from now on (IID) for the ease of typing :p
(you may wanna read more about the PE format and I recommend Matt Petrik tutorial published in the MSDN library).
Each IID is structured like this:
IMAGE_IMPORT_DESCRIPTOR struct
OriginalFirstThunk dd 0 ; RVA to original unbound IAT (ImportAddressTable)
; < table of RVAs to functions names
TimeDateStamp dd 0 ; usually not used
ForwarderChain dd 0 ; usually not used
Name dd 0 ; RVA to DLL name
FirstThunk dd 0 ; RVA to IAT array < table of doors to the func.
IMAGE_IMPORT_DESCRIPTOR ends
I think things are becoming abit mysterious.. let's take the reverseme as an example to udnerstand what's described so far.. use LordPE to open the file and click on the 'Directories' now hit the 'L' button beside the ImportTable and take alook @ the first DLL used 'user32.dll', the IID of it would be the following:
ImageImportDescriptor:
OriginalFirstThunk: 0x00002108
TimeDateStamp: 0x00000000 (GMT: Thu Jan 01 00:00:00 1970)
ForwarderChain: 0x00000000
Name: 0x0000221C ("user32.dll")
FirstThunk: 0x00002018
the OriginalFirstThunk holds the RVA of the table of functions used, check that out, at RVA 2108 you should see something like this:
xx xx xx xx xx xx xx xx 9A 21 00 00 A8 21 00 00
B4 21 00 00 C6 21 00 00 8C 21 00 00 EA 21 00 00
F8 21 00 00 0C 22 00 00 78 21 00 00 68 21 00 00
40 21 00 00 56 21 00 00 DA 21 00 00 00 00 00 00
and because the OFT (OriginalFirstThunk) holds RVAs to the func. names that means at addr 219a you will find:
80 01 4C 6F 61 64 43 75 72 73 6F 72 41 00
which stands for the LoadCursorA func.
good, now TimeDateStamp and ForwarderChain aren't used usually and if so they don't matter to us so you can ignore them.. the Name holds the RVA to the DLL file name used, finally we come to the FirstThunk which holds RVA to the table of doors (those doors are used to call the functions and filled by the compiler), so at RVA 2018 you will see this:
xx xx xx xx xx xx xx xx 9A 21 00 00 A8 21 00 00
B4 21 00 00 C6 21 00 00 8C 21 00 00 EA 21 00 00
F8 21 00 00 0C 22 00 00 78 21 00 00 68 21 00 00
40 21 00 00 56 21 00 00 DA 21 00 00 00 00 00 00
now wait a minute.. wtf! why the FT is the same as the OFT? not to complicate things I can say that the FT is used to correct the RVAs referenced by the OFT, means, the program when calling a function it uses the RVA referenced by the OFT but if something went wrong then it uses the RVA of the FT and if there were something wrong too it simply crashs or.. whatever :p
that may not be correct in some other programs.. take notepad.exe for example (XP build), if you check the IID of the DLLs used you see that the OFT points to table of RVAs to the func. names while the FT points to addresses like '08 1E 3D 76' which is actually '763d1e08' which is the direct addr of the 'PageSetupDlgW' func.
So what do we need to have IT working?
1- the RVA and the SIZE of the IT should be correct.
2- the IT should end with a closing header as mentioned above.
3- the FT (at least) should be correct for each DLL.
Fine, and what func. we will import?
Because we will be importing the func. needed manually we may need lots of 'em (assuming eh :p), so we will look at this again, why should we import all the needed funcs. while we need to only import two funcs. which are the 'LoadLibraryA' and 'GetProcAddress' then using 'em we can get any other func. we want.
but that's ain't the problem, once we know how to rebuild the IT we can have 'em imported and everything will be just another piece of.. code
Let's import some!
We will first import the func. 'LoadLibraryA' to the REme which is in the 'kernel32.dll' file so, we can either create another IID for this file to have the func. or have the func. imported from the same IID of the 'kernel32.dll' file.. Ofcourse for each way there is an advantage and disadvantage but the common problem between 'em is that we will have to fsck our brain out trying to locate more space (if needed) for our new func. so let's see which way is the easiest to take..
The 1st way as i mentioned works by adding another IID to the IT, that means that we need some cave (unused space) after the IT.. so let's check that out..
the IT starts @ RVA 20a0, if you check it out you will see that if we wanted to expand it to insert another RVA poiting to the new IID we need unused space after it but 'damnit' the OFT RVAs are stored there.. so unless we wanna rewrite the OFT table again and fix the RVA in the IT we won't use this way.
the other way is by adding the new func. to the existing IID of the kernel32.dll file, the problem here, again, is that we don't have enough space after the table of the RVAs, below you see the table of the RVAs referenced by the FT
and if we wanted to use this way we will have to move the whole table of RVAs of the FT somewhere else, fix the RVA in IT so unless you wanna go through all of this we will not choose this way..
now fsck! we have to choose one of the ways above.. not sure? well, i've been inspired by my neighbore (nice girl ;) to pick up the 1st way of messing with the IT RVAs because (as she seemed to tell me :p) we won't be worring about fscking up any byte while moving, we will only be looking for an unused space in the .exe were we will have the IT in it, adding the new RVA of the new IID which will be located also in some other cave, and finally we will have to fix the addr of the IT in the PE and the SIZE of it.. I must admit that she know somethings :], i think im gonna ask her out
Bust a Move:
In here I'll list the steps we have to accomplish in order to have everything working..
1- Find a suitble cave
2- Insert the old IT in it, and before closing it..
3- Adding our new RVA of the new IID, then closing the IT
4- Inserting the new IID of the kernel32.LoadLibraryA and kernel32.GetProcAddress funcs.
5- Fixing the RVA and SIZE of the IT in the PE
6- Testing and fixing if we overlooked something.
the cave we are looking for should be at least 100bytes (64h) [old IT size = 80bytes (50h) + new IID (4bytes * 5 sections //OriginalFirstThunk-TimeDateStamp-ForwarderChain-Name-FirstThunk//) = 20bytes -> 100bytes in total], I'll choose cave @ RVA = 22c0 located in the .rdata section.
now in the new IID we will need the names of the funcs. we wanna import so we will have to add 'em to the executable, no problem.. we will place 'em @ RVA = 2294 and they should look like this
remember that each func. struct as (ordinal / hint / func_name / end_byte) that's why we typed (00 00 LoadLibraryA 00), the function can be called using the ordinal but because we will use the name of it so we set both the ordinal and the hint to NULL and we terminate the func. with a 00 too
now we will move and rewrite the IT @ RVA = 22c0, this is what it should look like
in the picture you see that I've made the OFT and the FT the same with the RVA = 2330 (30 23) where I'll place the FT RVAs that point to the funcs.
the following picture shows the 'not so' final step
finally, let's fix the RVA and the SIZE of the IT so, with LordPE change the RVA of the IT from 20a0 to 22c0 and its SIZE from 50 to 64 and press the 'Save' button.. (start praying..), now click again on the 'L' button.. if everything was done correctly then you should see the kernel32.dll new IID at the end with the funcs. you imported manually.. i mean like this
so if your IT doesn't look like this, or LordPE doesn't show any IT and say there is some error then you obviously fscked something! go back and check everything you done.. (you know now why it's better to care about importing 'LoadLibraryA' and 'GetProcAddress' and leave the rest for those two funcs.. sometimes i had to rewrite few hundreds of bytes, noting, moving, testing, fixing, and fscking all the time! ;D)
Welcome to next level, resourcing some!
In this level we'll have to add a button with the caption 'Show' to the .exe without any resource editor.. don't think rebuilding the IT was 'hard'.. you will change your mind in a sec :p
You need to understand what's called the IMAGE_RESOURCE_DIRECTORY (which we'll call from now on IRD)
You know that any compiler out there puts the resource used by the program GUI in a section called '.rsrc' that can be found in any program.. the .rsrc section contains the information used to display buttons, menus, dialogs etc.. each resource consists of several IRDs and each IRD may point to another IRD (secondary one) or to an IMAGE_RESOURCE_DIRECTORY_ENTRY (we'll call it IRDE) which we'll be looking for coz it's the one that contains the information about a specific item of the program resource.. such as buttons for ex.
The IRD is structured like this
IMAGE_RESOURCE_DIRECTORY struct
DWORD Characterstics
DWORD TimeDateStamp
WORD MajorVersion
WORD MinorVersion
WORD NumberOfNamedEntries
WORD NumberOfIdEntries
IMAGE_RESOURCE_DIRECTORY ends
so you see that each IRD is 16 bytes long, we(?), reversers :), don't care about the IRD but where begins the next data flow (the IRDE), so we move forward 16 bytes to the next IRD or IRDE..
each IRDE is 8 bytes long and structured like follows
IMAGE_RESOURCE_DIRECTORY_ENTRY struct
DWORD Name
DWORD OffsetToData
IMAGE_RESOURCE_DIRECTORY_ENTRY ends
usually the IRDE comes in order: Icon, Menu, Dialogs, etc..
let's take an example, in our target the RVA of the .rsrc section is 4000, if you check there you will be at the IRD (#0), it looks like
00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00
so you see that NumberOfIdEntries is 5, pass those 16 bytes to reach the the IRDE (#0) of the icon resource.. looks like
03 00 00 00 38 00 00 80 04 00 00 00 50 00 00 80
05 00 00 00 68 00 00 80 0E 00 00 00 80 00 00 80
the 1st 8 bytes are the IRDE of the icon resource, so pass 'em and take the next 8 bytes which are the IRDE of the menu resource, pass those too and take the next 8 bytes which are
05 00 00 00 68 00 00 80
we care about the last 4 bytes of the IRDE which are '68 00 00 80', if the most significiant byte (high byte) is set (set to 80) then the rest of bytes points to another IRD which (in this example) is located @ offset '0068' -> RVA = 'beginning of .rsrc:4000 + offset:68 = 4068' so go there..
again, pass 16 bytes and you will have
E8 03 00 00 E0 00 00 80
the high byte is set so '00 E0' is an offset to next IRD, move to '40E0', pass 16 bytes from there and you will have
09 04 00 00 48 01 00 00
the high byte isn't set so the last four bytes are an offset to the IMAGE_RESOURCE_DATA_ENTRY (let's call it IRDAE) which holds the information about the dialog resource we were looking for.. goto 'RVA:4000 + Offset:0148 = RVA:4148' and you will have the values of the IRDAE which is represented as
IMAGE_RESOURCE_DATA_ENTRY struct
DWORD OffsetToData
DWORD Size
DWORD CodePage
DWORD Reserved
IMAGE_RESOURCE_DATA_ENTRY ends
the bytes you will be @ are
00 42 00 00 4A 01 00 00 00 00 00 00 00 00 00 00
so the RVA (not offset) to the needed data is '4200' and the size of 'em is '14A' :) (note: some may say use any damn program to get these info but i say to him/her, go away.. lamer!)
I'm trying to make this tutorial as short as possible putting in mind explaining everything i can think of.. I don't wanna bore you with the structure of Dialogs, i think after all this structuring you should be able to understand it by yer self.. do your own searchs and maybe in some other tutorial I'll talk about the structure of resource items, who really knows, I've all the summer ahead ;)
Structure of a button:
We're going now to add a button to the dialog so how do we do that? do we have enough unused space?
first of, let me show you the structure of any button on a dialog, please note that i write the skeleton of this structure by myself, i didn't really find (or didn't search enough) for the exact params of the structures so i hope there is no major difference..
Button struct
DWORD ?????? ; I don't know what is it for
; lpWindowName? or lpClass!? (help :[)
DWORD ExStyle
DWORD Style
WORD LeftPos
WORD TopPos
WORD Width
WORD Height
DWORD ID
WORD HelpID
WORD ?????? ; I'm not sure of this too
; I know it's not TabOrder thing
; for buttons it's "80 00" always, so is it lpClass?
DD Caption
Button ends
Ofcourse as any other resource the button must be closed with a DWORD filled with zeros. Now to add our button 'Show' we need exactly (???: 4bytes + exstyle: 4bytes + style: 4bytes + left: 2bytes + top: 2bytes + width: 2bytes + height: 2bytes + ID: 4bytes + helpid:2bytes + ???: 2bytes + caption: 8bytes //S.h.o.w// + closing: 4bytes) = 40bytes but we don't have that space after the IRDAE so what we're gonna do? i won't talk alot about moving the IRDAE too but we will only use some of the bytes used to display some useless text on the dialog which are ' - Written for [C.O.D.E] ' terminating everything we won't use so in result the new IRDAE would look like this
well, after you test the changes you've made you'll notice that the label @ the bottom of the dialog is gone.. I don't really know why as I've changed everything correctly (I think) and I didn't do anything to its properties or something, I just used some of its bytes so what went wrong is something I don't know, if you think you know please mail me about this (help, again :/)
anyway, the .exe now working just fine and we(?)'ve successfully added the needed button :) so Cong!
To be continued:
This is the end of part 1 of this tutorial, i wanted to continue but i got tired after setting in my chair for about 10 hours so far.. and yeah, i got myself a date with my neighbore ;) so 'till next part, read this one!
In the end:
I'de like to send my greetings to: Fusion team members (some have been away for awhile, i hope to see 'em back on to the crack soon), hav0k, Fenri (for his short notes about menu resourcing) and all r3^3r$3r$ in the world (may the tool be with you, ouch!)
any comments/ideas are very welcomed, help me continue my journey!
Xacker/Fusion